from tkinter import Frame, Label, Checkbutton, Scrollbar, Canvas


class TableWithCheckbuttonPage(Frame):
    def __init__(self, master, **kwargs):
        super().__init__(master)
        if kwargs is None:  # 单选按钮样式属性
            self.all_style = {'all': ('font', 'bg', 'fg')}
        else:
            self.all_style = kwargs
            if 'all' not in self.all_style:
                self.all_style['all'] = ('font', 'bg', 'fg')

        frm = Frame(self)
        frm.pack(fill='both', expand=True)
        # 创建 Canvas
        self.canvas = Canvas(frm, bd=0, background="yellow")
        self.canvas.pack(fill='both', side='left', expand=True)  # Canvas 占据整个窗口

        # # # 创建垂直滚动条
        self.scy = Scrollbar(frm, orient="vertical", command=self.canvas.yview)
        self.scy.pack(fill="y", side="right", expand=False)  # 滚动条在右侧，不扩展
        self.canvas.configure(yscrollcommand=self.scy.set)

        # 创建水平滚动条
        self.scx = Scrollbar(self, orient="horizontal", command=self.canvas.xview)
        self.scx.pack(fill="x", side="bottom", expand=False)  # 滚动条在底部，不扩展
        self.canvas.configure(xscrollcommand=self.scx.set)

        self.tframe = Frame(self.canvas, bd=0, bg='black', width=1000, height=30)
        self.canvas.create_window((0, 0), window=self.tframe, anchor="nw")

        self.frame = Frame(self.canvas, bg='red', width=1000, height=500)
        self.canvas.create_window((0, 30), window=self.frame, anchor="nw")

        self.scx.bind("<MouseWheel>", self.mouse_bind_x)
        self.tframe.bind("<MouseWheel>", self.mouse_bind_x)
        self.scy.bind("<MouseWheel>", self.mouse_bind_y)
        self.frame.bind("<MouseWheel>", self.mouse_bind_y)
        self.bind("<Configure>", self.update_scrollregion)

        self.datas = []  # 数据 二维列表
        self.index = []  # 被选中的数据索引
        self.index_page = 0  # 页面索引
        self.labels = []  # 组件
        self.labels_title = []  # 组件
        self.ch = 0  # 行高
        self.rw = 0  # 单位列宽
        self.winw = 0  # 页面总宽度
        self.chh = 0  # 数据页总高度
        self.winh = 0  #
        self.needset = True  # 是否需要设置布局

    def update_scrollregion(self, event=None):
        # 确保所有内容都被渲染
        self.update_idletasks()
        # 计算新的滚动区域
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def mouse_bind_x(self, event):  # 鼠标滚轮滚动事件
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        if event.delta > 0:
            self.canvas.xview_scroll(-1, "units")
        else:
            self.canvas.xview_scroll(1, "units")

    def mouse_bind_y(self, event):  # 鼠标滚轮滚动事件
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        if event.delta > 0:
            self.canvas.yview_scroll(-1, "units")
        else:
            self.canvas.yview_scroll(1, "units")

    def res_style(self, name):
        if name == 't':
            style = self.all_style.pop('t', {})
        elif name == 'l':
            style = self.all_style.pop('l', {})
        else:
            style = self.all_style.pop('c', {})
        for val in self.all_style['all']:
            if (val in self.all_style) and (val not in style):
                style[val] = self.all_style[val]
        self.all_style[name] = style
        return style


if __name__ == '__main__':
    from tkinter import Tk
    root = Tk()
    root.geometry('500x500')
    app = TableWithCheckbuttonPage(root)
    app.pack(fill='both', expand=True)
    root.mainloop()
